home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Tools / Installers / Smaller Installer 1.1 / Hook Proc Examples / PersonalizeHook / PersonalizeHook.c next >
Encoding:
C/C++ Source or Header  |  1993-07-03  |  10.0 KB  |  310 lines  |  [TEXT/KAHL]

  1. /******************************************************************************
  2.     Smaller Installer © 1993 Bill Goodman, All Rights Reserved
  3. *******************************************************************************
  4.  
  5. Personalize Hook Example
  6.  
  7. This installer hook procedure prompts the user to enter a name and organization
  8. string which is used to personalize the installed application. These strings
  9. are stored in an STR# resource (ID 1000) in the installed application. The user
  10. name is string #1 and the organization name is string #2. The strings are also
  11. saved in an "info" file on the installer startup disk so that subsequent
  12. installations will use the same personalization info.
  13.  
  14. To use this hook procedure, you must compile this code and create a code
  15. resource with type 'SICR' and an ID of 500. This resource should be
  16. non-preloaded, nonpurgeable, unlocked, unprotected and non-sysheap. Copy this
  17. resource to your installer's resource file.
  18.  
  19. Set the STR# resource in the "PersonalizeHook.Misc.rsrc" file to specify the
  20. full path to the application being installed. Change all references to "XXXX"
  21. in the DITL resources to use your application's name. Add all the resources in
  22. "PersonalizeHook.Misc.rsrc" to your installer's resource file.
  23.  
  24. Copy the "Volume Info" file to the distribution disk containing the installer.
  25. This file must contain 512 bytes of data (preferably random in appearance).
  26. The first byte must be 0xFF. This file may be invisible if desired.
  27.  
  28. Add an STR#[1000] resource to your application. The hook will modify the values
  29. in this resource after the application is installed. Add whatever code is
  30. appropriate to display these personalization strings in your application.
  31.  
  32. ******************************************************************************/
  33.  
  34. #include <SetUpA4.h>
  35. #include <GestaltEqu.h>
  36. #include "SIHookProc.h"
  37.  
  38.  
  39. /******************************************************************************
  40.     Module Internal Function Prototypes
  41. ******************************************************************************/
  42. void SetTargetVolFunction(void);
  43. void EndInstallFunction(void);
  44.  
  45.  
  46. /******************************************************************************
  47.     Constant Declarations
  48. ******************************************************************************/
  49. /* Dialog Definitions */
  50. #define nameDlg                500    /* Name and organization entry dialog */
  51. #define ok_nameDlg            1        /* OK button */
  52. #define name_nameDlg            3        /* Name edit text item */
  53. #define org_nameDlg            4        /* Organization edit text item */
  54.  
  55. /* Alert Definitions */
  56. #define damagedAlrt            501    /* "The installer disk is damaged. Please be sure you are using the original installer disk." */
  57. #define nameErrAlrt            502    /* "Please enter your name AND your organization's name." */
  58. #define lockedAlrt            503    /* "The installer disk is locked. Please unlock it and try again." */
  59. #define installAlrt            504    /* "An error occurred while installing the “XXXX” application. Please remove all files in the “XXXX” folder and try again." */
  60.  
  61. /* Indexed String Definitions */
  62. #define filePathID            500    /* File path string */
  63. #define personalizeID        1000    /* Personalization resource */
  64.  
  65.  
  66. /******************************************************************************
  67.     Module Variables Declarations
  68. ******************************************************************************/
  69. SIHookParmBlk *parms;                        /* Global pointer to parameter block */
  70. Boolean firstCallDone = false;            /* Set after first hook proc call */
  71. Str31 infoFilename = "\pVolume Info";    /* Name of info file */
  72. Str255 userName;                                /* User name string */
  73. Str255 userOrg;                                /* User organization string */
  74.  
  75.  
  76. /*****************************************************************************/
  77. pascal void main(
  78.         SIHookParmBlk *parmBlk    /* Pointer to parameter block */
  79.         )
  80. /******************************************************************************
  81.     This is the main entry point for the installer hook procedure.
  82. ******************************************************************************/
  83. {
  84. RememberA0();    /* This is necessary to access any global variables */
  85. SetUpA4();
  86. parms = parmBlk;
  87.  
  88. switch (parms->function)
  89.     {
  90.     case siHookSetTargetVol:
  91.         SetTargetVolFunction();
  92.         break;
  93.  
  94.     case siHookEndInstall:
  95.         EndInstallFunction();
  96.         break;
  97.     }
  98. RestoreA4();
  99. }
  100.  
  101.  
  102. /*****************************************************************************/
  103. void SetTargetVolFunction(void)
  104. /******************************************************************************
  105.     Input parameters:
  106.         "targetVRefNum" - Volume reference number of target volume
  107.         "groupAPFlags", "groupQUSel", "groupVZSel" - Groups currently selected
  108.                                                                     for installation
  109.     Returns:
  110.         "groupAPFlags", "groupQUSel", "groupVZSel" - New installation groups
  111.  
  112.     This function is called at startup and whenever the target volume is
  113.     changed.
  114.  
  115.     NOTE: This code calls ExitToShell to terminate installer execution. This is
  116.     acceptable for terminating execution on the first SetTargetVol call;
  117.     however, it should not be used to terminate execution during other
  118.     SetTargetVol calls.
  119. ******************************************************************************/
  120. {
  121. OSErr error;
  122. short infoPathNum;
  123. long rwCnt;
  124. short index;
  125. DialogPtr dlgPtr;
  126. short item;
  127. short tmpType;
  128. Handle tmpHdl;
  129. Rect tmpRect;
  130.  
  131. if (firstCallDone)
  132.     return;    /* Execute this code only for the first SetTargetVol function call */
  133. firstCallDone = true;
  134.  
  135. /* Open the info file */
  136. error = HOpen(-SFSaveDisk, fsRtDirID, infoFilename, fsCurPerm, &infoPathNum);
  137. if (error != noErr)
  138.     goto DamagedError_Closed;
  139.  
  140. /* Read the user name string */
  141. rwCnt = 256;
  142. error = FSRead(infoPathNum, &rwCnt, userName);
  143. if (error != noErr)
  144.     goto DamagedError;
  145.  
  146. /* Read the user organization string */
  147. rwCnt = 256;
  148. error = FSRead(infoPathNum, &rwCnt, userOrg);
  149. if (error != noErr)
  150.     goto DamagedError;
  151.  
  152. if (userName[0] == 0xFF)
  153.     {    /* Personalization strings have not been specified - prompt user to enter */
  154.     dlgPtr = GetNewDialog(nameDlg, NULL, (WindowPtr) -1L);
  155.     if (dlgPtr == NULL)
  156.         goto FatalError;
  157.     for (;;)
  158.         {
  159.         ModalDialog(NULL, &item);
  160.         if (item != ok_nameDlg)
  161.             goto CleanupAndTerminate;    /* User cancelled dialog */
  162.     
  163.         /* Read strings from dialog */
  164.         GetDItem(dlgPtr, name_nameDlg, &tmpType, &tmpHdl, &tmpRect);
  165.         GetIText(tmpHdl, userName);
  166.         GetDItem(dlgPtr, org_nameDlg, &tmpType, &tmpHdl, &tmpRect);
  167.         GetIText(tmpHdl, userOrg);
  168.     
  169.         /* Validate strings  */
  170.         if ((userName[0] != 0) && (userOrg[0] != 0))
  171.             break;
  172.     
  173.         CautionAlert(nameErrAlrt, NULL);    /* "Entries are invalid" */
  174.         }
  175.     DisposDialog(dlgPtr);
  176.  
  177.     /* Complement the characters in the name and organization strings to disguise them */
  178.     for (index = 256; --index >= 0;)
  179.         userName[index] = ~userName[index];
  180.     
  181.     for (index = 256; --index >= 0;)
  182.         userOrg[index] = ~userOrg[index];
  183.     
  184.     /* Save the strings in the info file */
  185.     error = SetFPos(infoPathNum, fsFromStart, 0);
  186.     if (error != noErr)
  187.         goto FatalError;
  188.     
  189.     rwCnt = 256;
  190.     error = FSWrite(infoPathNum, &rwCnt, userName);
  191.     if (error != noErr)
  192.         goto WriteError;
  193.     
  194.     rwCnt = 256;
  195.     error = FSWrite(infoPathNum, &rwCnt, userOrg);
  196.     if (error != noErr)
  197.         goto WriteError;
  198.     }
  199.  
  200. /* Complement the characters in the name and organization strings to */
  201. /* return the strings to normal format */
  202. for (index = 256; --index >= 0;)
  203.     userName[index] = ~userName[index];
  204.  
  205. for (index = 256; --index >= 0;)
  206.     userOrg[index] = ~userOrg[index];
  207.  
  208. error = FSClose(infoPathNum);
  209. if (error != noErr)
  210.     goto WriteError;
  211. return;    /* Good completion */
  212.  
  213. /*** Error exits ***/
  214.  
  215. /* Error occured while accessing the info file */
  216. DamagedError:
  217. FSClose(infoPathNum);
  218.  
  219. DamagedError_Closed:
  220. StopAlert(damagedAlrt, NULL);    /* "Disk is damaged" */
  221. ExitToShell();
  222.  
  223. /* Error occurred while writing the info file */
  224. WriteError:
  225. if ((error == vLckdErr) || (error == wPrErr))
  226.     {    /* Volume is locked */
  227.     StopAlert(lockedAlrt, NULL);    /* "Volume is locked" */
  228.     goto CleanupAndTerminate;
  229.     }
  230. goto DamagedError;
  231.  
  232. /* Fatal error occurred */
  233. FatalError:
  234. SysBeep(1);
  235.  
  236. /* Cleanup and terminate */
  237. CleanupAndTerminate:
  238. FSClose(infoPathNum);
  239. ExitToShell();
  240. }
  241.  
  242.  
  243. /*****************************************************************************/
  244. void EndInstallFunction(void)
  245. /******************************************************************************
  246.     Input parameters:
  247.         "targetVRefNum" - Volume reference number of target volume
  248.         "groupAPFlags", "groupQUSel", "groupVZSel" - Groups currently selected
  249.                                                                     for installation
  250.         "completionSts" - Indicates any errors which occurred during installation
  251.     Returns:
  252.         "result" - Hook result code
  253.  
  254.     This function is called at the end of the installation process.
  255. ******************************************************************************/
  256. {
  257. Str255 filePath;
  258. short applResFileNum = -1;
  259. Handle resHdl;
  260. long resSize;
  261. unsigned char buf[514];
  262.  
  263. if (parms->completionSts != siHookComplete)
  264.     return;    /* Do not try to install resource if all files weren't installed */
  265.  
  266. /* Build the personalization resource */
  267. buf[0] = 0;
  268. buf[1] = 2;
  269. BlockMove(userName, &buf[2], (short) userName[0] + 1);
  270. BlockMove(userOrg, &buf[(short) userName[0] + 3], (short) userOrg[0] + 1);
  271.  
  272. /* Open the installed application file */
  273. GetIndString(filePath, filePathID, 1);
  274. if (filePath[0] == 0)
  275.     goto Fail;
  276. SetResLoad(false);    /* Prevent loading of resources with preload attribute */
  277. applResFileNum = HOpenResFile(parms->targetVRefNum, 0, filePath, fsRdWrPerm);
  278. SetResLoad(true);
  279. if (applResFileNum == -1)
  280.     goto Fail;
  281.  
  282. /* Update the personalization resource in the installed application file */
  283. resHdl = Get1Resource('STR#', personalizeID);
  284. if (resHdl == 0)
  285.     goto Fail;
  286. resSize = (long) userName[0] + (long) userOrg[0] + 4;
  287. ReallocHandle(resHdl, resSize);
  288. if (MemError() != noErr)
  289.     goto Fail;
  290. BlockMove(buf, *resHdl, resSize);
  291. ChangedResource(resHdl);
  292. if (ResError() != noErr)
  293.     goto Fail;
  294. WriteResource(resHdl);
  295. if (ResError() != noErr)
  296.     goto Fail;
  297. CloseResFile(applResFileNum);
  298. if (ResError() != noErr)
  299.     goto Fail;
  300. return;    /* Note that it is not necessary to set the result if no error */
  301.  
  302. /* Error occurred during update */
  303. Fail:
  304. parms->result = siHookAbort;
  305.  
  306. if (applResFileNum != -1)
  307.     CloseResFile(applResFileNum);
  308. StopAlert(installAlrt, NULL);
  309. }
  310.